#################################################################################
# Depricated - still being used by Copy-CustomFiles function below
function Get-RootFolder
{
  param( $files )
  $files = $files | where-object { $_ -is [System.IO.FileInfo] }
  $root = ""
  foreach ($file in $files)
  {
    if ($root.length -eq 0 -or $root.length -gt $file.DirectoryName.length)
    {
      $root = $file.DirectoryName
    }
  }
  $root
}

#################################################################################
function Get-DeployPath
{
  param( $server, $app )
  
    $filesPath = [System.IO.Path]::Combine( $server.Volume , $app.DestFolder )
    $deployPath = [System.IO.Path]::Combine( "\\" + $server.FQName , $filesPath )
    $deployPath
}
####################################################################################
## Copy-Envfiles - handles files defined in the <envfile> node(s) of deploymentEnv.xml
## <envfile> can have Dest or RelativeDest. Dest is default for handling envconfig files
####################################################################################
function Copy-EnvFiles
{
  param( $server, $app )
  $deployPath = Get-DeployPath $server $app
  foreach ( $EnvFile in $app.EnvFiles )
  {
    if ($EnvFile.Env -eq $Env.Name -and $Envfile.Dest -ne $null)
    {
      $destFile = [System.IO.Path]::Combine( $deployPath , $EnvFile.Dest )
      $msg = "Copying $($EnvFile.SrcFile.Name) to " + $deployPath + "\" +  $EnvFile.Dest 
      if (Should-Process $msg ([REF]$AllAnswer) "" -Verbose:$Verbose -Confirm:$Confirm -Whatif:$Whatif)
      { 
        $env_targetdir = Split-Path $destFile
        if (! (Test-Path $env_targetdir) )
        {
          Log-Message "Copying $($EnvFile.SrcFile.name) to $($destFile)" -nonewline
	        [void] (New-Item $env_targetdir -ItemType directory)
        }

        if ( Test-Path $destFile )
        {
	        Remove-Item $destFile -Force
        }

        Log-Message "Copying $($EnvFile.SrcFile.name) to $($destFile)" -nonewline
        copy-item $EnvFile.SrcFile.FullName $destFile -recurse -force 
        Log-Message  "`t[OK]" -foregroundcolor green
      }  
    }
    if ($EnvFile.Env -eq $Env.Name -and $EnvFile.RelativeDest -ne $null)
    {
      $VolumeDeployPath = [System.IO.Path]::Combine( "\\" + $server.FQName, $server.Volume )
      $destFile = [System.IO.Path]::Combine( $VolumeDeployPath, $EnvFile.RelativeDest )
      $msg =  "Copying $($EnvFile.SrcFile.Name) to " + $VolumeDeployPath + "\" +  $EnvFile.RelativeDest
       if (Should-Process $msg ([REF]$AllAnswer) "" -Verbose:$Verbose -Confirm:$Confirm -Whatif:$Whatif)
      { 
        if( test-path $destFile )
        {
          remove-item -Path $destFile -recurse -force
          Log-Message "Copying $($EnvFile.SrcFile.name) to $($destFile)" -nonewline
        	copy-item $EnvFile.SrcFile.FullName $destFile -recurse -force 
        	Log-Message  "`t[OK]" -foregroundcolor green
        }
        else
        {
          Log-Message "Copying $($EnvFile.SrcFile.name) to $($destFile)" -nonewline
        	$null = new-item -path $destFile -force -type "file"
        	copy-item $EnvFile.SrcFile.FullName $destFile -recurse -force 
        	Log-Message  "`t[OK]" -foregroundcolor green
        }
      }  
    } 
  }  	
}
####################################################################################
## Copy-CustomFiles - handles files defined in the <envCustom> node(s) of deploymentEnv.xml
## This allows copying of any file or folder from the deployment package to any
## path on the server.
####################################################################################
function Copy-CustomFiles
{
  param( $server )
  foreach ( $EnvCustom in $app.EnvCustoms)
  {
    if ($EnvCustom.Env -eq $Env.Name -and $EnvCustom.ImplicitDest -ne $null)
    {
      $dest = [System.IO.Path]::Combine( "\\" + $server.FQName, $EnvCustom.ImplicitDest )
      if ( $EnvCustom.SrcFile.count -gt 1 )
      {
        $parentfolder = Get-RootFolder ($EnvCustom.SrcFile)
        $msg = "Copying $($parentfolder) to " + $dest
      }
      else
      {
        $msg = "Copying $($EnvCustom.SrcFile[0]) to " + $dest
      }
      if (Should-Process $msg ([REF]$AllAnswer) "" -Verbose:$Verbose -Confirm:$Confirm -Whatif:$Whatif)
      { 
        if ( $EnvCustom.SrcFile.count -gt 1 )
        {
          if( test-path $dest )
  			  {
  			    remove-item -Path $dest -recurse -force 
  			  }
          Log-Message $msg -nonewline
          foreach ( $file in $EnvCustom.SrcFile )
          { 

            if( ![System.IO.Directory]::Exists($dest) )
            { 
              $newDir = [System.IO.Directory]::CreateDirectory($dest);
            }
            copy-item $file.fullname $dest -recurse -force
          }
        }
        else
        {
          #  Copy only one file - 
          if( test-path $dest )
  			  {
  			    remove-item -Path $dest -force 
  			  }
          Log-Message $msg -nonewline
          foreach ( $file in $EnvCustom.SrcFile )
          { 
            if( !(test-path $dest) )
            {   
              $newDir = split-path $dest
              if (!( Test-Path $newdir))
			        {
              $null = New-Item $newDir -ItemType directory
              }
            }
            copy-item $file.fullname $dest -recurse -force
          }
        }
        Log-Message  "`t[OK]" -foregroundcolor green
      }  
    }     
  }  	
}
#################################################################################
function find-FolderMatch($regex, $destfiles)
{
	$foundmatch = $null
	foreach ($item in $destFiles)
	{
		if ($item -is [system.io.DirectoryInfo])
		{
		#does the item match the pattern
			if ($item.fullname -match $regex)
			{
				$foundMatch = $item.fullname
				Log-Message "Excluding deletion of $foundmatch and its contents" -fore yellow
				return $foundMatch
			}
		}
	}
}
#################################################################################

function Delete-ApplicationFiles
{
  param( $server, $app )
  
  #if not true handles envCustom files
  if (!($app.DestFolder.length -gt 0))
  {
    $msg = "Deleting $($app.name)  "
    if (Should-Process $msg ([REF]$AllAnswer) "" -Verbose:$Verbose -Confirm:$Confirm -Whatif:$Whatif)
    { 
      Log-Message $msg -nonewline
# Why is this commented out?!
#       $dest = $EnvCustom.ImplicitDest
#       
#       if( test-path $dest )
#   	  {
#   		  remove-item -Path $dest -recurse -force 
#   	  }
  	  Log-Message  "`t[OK]" -foregroundcolor green
    }
  }
  elseif ([system.String]::IsNullOrEmpty($app.delete)) #standard deletion of appfiles
  {
    $deployPath = Get-DeployPath $server $app
    if( test-path $deployPath )
    {

      $destFiles=Get-ChildItem $deployPath -recurse 
			#dv $destFiles "before"
			if($app.excludeFolders)
			{
				foreach ($regex in $app.excludeFolders)
				{
					[array]$matchingFolders += find-FolderMatch $regex $destfiles
				}
				foreach ($folder in $matchingFolders)
				{
					[array]$exclusionList += gci $folder -recurse | ?{$_ -is [system.IO.FileInfo]}
				}
			}
			$destFiles = $destfiles | ?{$_ -is [system.IO.FileInfo]}
			$exclusionList | %{$destFiles = $destFiles -notlike $_}
			if($app.excludeFiles)
			{	
				$app.excludeFiles |%{Log-Message "Excluding delete of files that match pattern $_" -ForegroundColor yellow }
				$app.excludeFiles |%{$destFiles = $destFiles -notlike $_}
			}
			$destFiles = $destFiles -notlike "App_offline.htm"
			if ($destFiles.count -gt 0)
			{
				$msg = "Deleting " + $destFiles.count  + " files from " + $deployPath
			}
			else
			{
				$msg = "No files to delete in $deployPath"
			}
			if(Should-Process $msg ([REF]$AllAnswer) "" -Verbose:$Verbose -Confirm:$Confirm -Whatif:$Whatif)
			{
				$destDir = Get-Item $deployPath -force
				if( $destDir -ne $null -and $destFiles.count -gt 0)
				{
					Log-Message $msg -nonewline
					foreach ($removal in $destFiles)
					{
						$cnt += 1 
						ReTry "Delete Files on " {Remove-Item -Path $removal.FullName -force } -AllowSkip #-ShowStatus
	
						write-progress -id 1 -activity "Deleting Files" `
												-status "Progress:" `
												-currentOperation "Delete $removal" `
												-percentcomplete ($cnt/$destFiles.count*100)
	
					}
						Log-Message  "`t[OK]" -foregroundcolor green
				}
			}
    }
    else
    # add better feed back if no access to path due to rights
    {
      #throw "Unable to verify $deployPath. Manually Verify mapped drive access." 
	  Log-Message "Nothing to delete from $deployPath. Manually Verify mapped drive access." 
    }
  }  
}

#################################################################################
function Copy-ApplicationFiles
{
  param( $server, $app )
  
  if (!($app.DestFolder.length -gt 0))
  {
    Copy-CustomFiles $server
  }
  else 
  {
		[system.IO.DirectoryInfo]$appRoot = $app.root
		$appRootLength = $appRoot.fullname.length
		
    $deployPath = Get-DeployPath $server $app
		
    $msg = "Copying $($app.files.count) files to " + $deployPath
    if (Should-Process $msg ([REF]$AllAnswer) "" -Verbose:$Verbose -Confirm:$Confirm -Whatif:$Whatif)
    {  
      Log-Message $msg -nonewline
			
      $cnt = 0
      foreach ($file in $app.files)
      {
        $cnt += 1 
        [string]$relativePath = $file.DirectoryName.substring($appRootLength);
        # if the relative path contains a subdirectory, then create a subdirectory under the deploy path
        [string]$copyPath = [System.IO.Path]::Combine( $deployPath, $relativePath.TrimStart('\') );	
        $relFilePath = $relativePath + $file.Name
        if( ![System.IO.Directory]::Exists($copyPath) )
        { 
          $newDir = [System.IO.Directory]::CreateDirectory($copyPath);
        }
        ReTry "Copy Files " {copy-item $file.fullname $copyPath -Force} -AllowSkip #-ShowStatus
        
        write-progress -id 1 -activity "Copying Files" `
                       -status "Progress:" `
                       -currentOperation "Copy $relFilePath" `
                       -percentcomplete ($cnt/$app.files.count*100)
         	 
      }
      Log-Message  "`t[OK]" -foregroundcolor green
    }
  }  
  Copy-EnvFiles $server $app
}
